﻿using System;
using System.Collections.Generic;
using OxyPlot.Series;
using VEGA.Algorithm;
using VEGA.Algorithm.Elements;

namespace DesigneSpaceExplorerVEGA.Adapters
{
    class ViewVegaAdapter
    {
        private Windows.VegaWindow _window;
        private Vega _vega;
        public ViewVegaAdapter(Windows.VegaWindow window, Vega vega)
        {
            _window = window;
            _vega = vega;
        }

        public void Update()
        {
            _window.VegaPopulationCount = _vega.PopulationSize;
            _window.VegaCurrentGeneration = _vega.CurrentGeneration;

            _window.BestPerformanceConfiguration = GetBestPerformanceConfiguration();
            _window.BestPowerConsumptionConfiguration = GetBestPowerConsumptionConfiguration();

            foreach (var individual in _vega.LastEvaluated)
            {
                _window.WriteMessageToConsole(string.Format("IPC:{0,6} - POWER:{1,6}", individual.Ipc.ToString("F3"), individual.Power.ToString("F1")));
            }
            
        }

        private Individual _lastBestPerformanceIndividual;
        private Individual _lastBestPowerIndividual;

        private Individual GetBestPerformanceConfiguration()
        {
            
            var evaluatedPopulation = new List<Individual>(_vega.LastEvaluated);
            if(_lastBestPerformanceIndividual != null)
                evaluatedPopulation.Add(_lastBestPerformanceIndividual);
            evaluatedPopulation.Sort(
                (individual, individual1) => individual1.FitnessIpc.CompareTo(individual.FitnessIpc));

            _lastBestPerformanceIndividual = evaluatedPopulation[0];
            return evaluatedPopulation[0];
        }
        private Individual GetBestPowerConsumptionConfiguration()
        {
            var evaluatedPopulation = new List<Individual>(_vega.LastEvaluated);
            if (_lastBestPowerIndividual != null)
                evaluatedPopulation.Add(_lastBestPowerIndividual);
            evaluatedPopulation.Sort(
                (individual, individual1) => individual.FitnessPower.CompareTo(individual1.FitnessPower));

            _lastBestPowerIndividual = evaluatedPopulation[0];
            return evaluatedPopulation[0];
        }

        public List<ScatterPoint> GetLastGenerationPoints()
        {
            var population = _vega.LastEvaluated;
            var result = new List<ScatterPoint>();

            foreach (var individual in population)
            {
                var point = new ScatterPoint
                {
                    X = Math.Round(individual.Power, 4),
                    Y = Math.Round(1 / individual.Ipc, 4),
                    Size = 3
                };
                result.Add(point);
            }

            return result;
        }
        public List<ScatterPoint> GetScatterPoints(List<Individual> evaluatedIndividuals)
        {
            var population = evaluatedIndividuals;
            var result = new List<ScatterPoint>();

            foreach (var individual in population)
            {
                var point = new ScatterPoint
                {
                    X = Math.Round(individual.Power, 4),
                    Y = Math.Round(1 / individual.Ipc, 4),
                    Size = 3
                };
                result.Add(point);
            }

            return result;
        }
    }
}
